from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from utils.tencent.sms import send_sms_single
from django.conf import settings
from app01 import models
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
import random, redis, re, hashlib



def encryption(pwd):
    """
    加密
    :param pwd: 
    :return: 
    """
    s = hashlib.md5()
    s.update(pwd.encode('utf-8'))
    md5_pwd = s.hexdigest()
    return md5_pwd


def conn_redis(phone, code):
    """
    python与redis软件建立连接
    :return: 根据手机号码返回对应的验证码
    """
    # 直接连接redis
    conn = redis.Redis(host='192.168.1.5', port=6379, password='root', encoding='utf-8')
    # 设置键值：phone=code 且超时时间为60秒（值写入到redis时会自动转字符串）
    conn.set(phone, code, ex=60)
    # 根据键获取值：如果存在获取值（获取到的是字节类型）；不存在则返回None
    code = conn.get(phone)
    return code


from django.shortcuts import HttpResponse
from django_redis import get_redis_connection


def index(request):
    # 去连接池中获取一个连接
    conn = get_redis_connection("default")
    conn.set('nickname', "武沛齐", ex=10)
    value = conn.get('nickname')
    print(value)
    return HttpResponse("OK")


def send_sms(tpl, phone, code):
    """
    腾讯云短信
    :param request:
    :return:
    """
    # tpl = request.GET.get('tpl')
    template_id = settings.TENCENT_SMS_TEMPLATE.get(tpl)
    if not template_id:
        return HttpResponse('模板不存在')
    # code = random.randrange(1000, 9999)
    res = send_sms_single(phone, template_id, [code, ])
    if res['result'] == 0:
        return 200
    else:
        return res['errmsg']


def operate_code(request):
    """
    操作验证码
    一、将验证码存储在redis中

    二、给用户发送验证码
    :param request:
    :return:
    """
    tpl = request.GET.get('tpl')
    phone = request.GET.get('phone')
    code = random.randrange(1000, 9999)
    code = conn_redis(phone, code)
    status = send_sms(tpl, phone, code)
    if status == 200:
        return JsonResponse({'status': 200})
    else:
        return HttpResponse(status)


# 自定义注册form组件
class RegForm(forms.ModelForm):
    # 方法一：
    # 对手机号运用ModelForm内置校验器validators=[RegexValidator(r'^1[3-9]\d{9}'), '手机号格式错误'])
    # phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^1[3-9]\d{9}'), '手机号格式错误'])
    password = forms.CharField(label='密码',
                               min_length=6,
                               widget=forms.PasswordInput(),
                               error_messages={
                                   'required': '密码不能为空',
                                   'min_length': '密码长度不能小于6位！',
                               })

    re_pwd = forms.CharField(label='确认密码',
                             min_length=6,
                             widget=forms.PasswordInput(),
                             error_messages={
                                 'required': '确认密码不能为空',
                                 'min_length': '密码长度不能小于6位！',
                             })

    code = forms.CharField(label='验证码',
                           max_length=4,
                           error_messages={
                               'required': '验证码不能为空',
                           })

    class Meta:
        model = models.UserInfo
        fields = ['username', 'email', 'password', 're_pwd', 'phone', 'code']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'
            field.widget.attrs['placeholder'] = f"请输入{field.label}"
            field.widget.attrs['autocomplete'] = "off"

    # 方法二
    # 自定义校验器对手机号校验即局部钩子
    def clean_phone(self):
        phone = self.cleaned_data.get('phone')
        if re.match(r'^1[3-9]\d{9}', phone):
            return phone
        raise ValidationError('手机号格式不正确！')

    def clean_code(self):
        conn = redis.Redis(host='192.168.100.105', port=6379, password='250361py', encoding='utf-8')
        code = str(int(conn.get('code')))
        reg_code = self.cleaned_data.get('reg_code')
        if reg_code == code:
            return reg_code
        else:
            self.add_error('reg_code', '验证码错误')
            raise ValidationError('验证码错误')

    def clean(self):
        pwd = self.cleaned_data.get('password', '')
        re_pwd = self.cleaned_data.get('re_pwd')
        if pwd == re_pwd:
            self.cleaned_data['password'] = encryption(pwd)
            return self.clean_data

        self.add_error(re_pwd, '两次密码不一致！')
        raise ValidationError('两次密码不一致！')


def register(request):
    """
    注册
    :param request:
    :return:
    """
    form_obj = RegForm()
    if request.method == 'POST':
        form_obj = RegForm(request.POST)
        if form_obj.is_valid():
            form_obj.save()
            return HttpResponse('注册成功！')
    return render(request, 'app01/register.html', {'form_obj': form_obj})
